React Native 開発者向けの Flutter
このドキュメントは、React Native (RN) の適用を検討している開発者を対象としています。 Flutter を使用してモバイル アプリを構築するための既存の RN 知識。もし分かれば RN フレームワークの基礎を理解している場合は、このドキュメントを次の資料として使用できます。 Flutter 開発の学習を始める方法。
このドキュメントは、あちこちに移動して見つけてクックブックとして使用できます。 あなたのニーズに最も関連する質問。
JavaScript 開発者のための Dart の概要 (ES6)
React Native と同様に、Flutter はリアクティブ スタイルのビューを使用します。ただし、RN である一方で、 Flutter はネイティブ ウィジェットにトランスパイルされ、ネイティブ コードまでコンパイルされます。 Flutter は画面上の各ピクセルを制御し、パフォーマンスの問題を回避します。 これは JavaScript ブリッジが必要なために発生します。
Dart は習得が簡単な言語で、次の機能を備えています。
- Web を構築するためのオープンソースのスケーラブルなプログラミング言語を提供します。 サーバーとモバイルアプリ。
- C スタイルを使用するオブジェクト指向の単一継承言語を提供します。 AOT によってネイティブにコンパイルされた構文。
- オプションで JavaScript にトランスコンパイルします。
- インターフェイスと抽象クラスをサポートします。
JavaScript と Dart の違いの例をいくつか説明します。 下。
エントリーポイント
JavaScript には事前定義されたエントリがありません 関数 - エントリ ポイントを定義します。
// JavaScript
function startHere() {
// Can be used as entry point
}
Dart では、すべてのアプリにトップレベルが必要ですmain()
として機能する関数
アプリへのエントリポイント。
/// Dart
void main() {}
で試してみてくださいダーツパッド。
コンソールへの印刷
Dart でコンソールに出力するには、次を使用します。print()
。
// JavaScript
console.log('Hello world!');
/// Dart
print('Hello world!');
で試してみてくださいダーツパッド。
変数
Dart はタイプセーフです。静的な型チェックを組み合わせて使用します。 変数の値が常に一致することを確認する実行時チェック 変数の静的型。種類は必須ですが、 一部の型アノテーションはオプションです。 Dart は型推論を実行します。
変数の作成と割り当て
JavaScript では変数を型指定できません。
のダーツ、変数は明示的に 型付けされていないか、型システムが適切な型を自動的に推測する必要があります。
// JavaScript
let name = 'JavaScript';
/// Dart
/// Both variables are acceptable.
String name = 'dart'; // Explicitly typed as a [String].
var otherName = 'Dart'; // Inferred [String] type.
で試してみてくださいダーツパッド。
詳細については、を参照してください。ダーツのタイプシステム。
デフォルト値
JavaScript では、初期化されていない変数は次のとおりです。undefined
。
Dart では、初期化されていない変数の初期値は次のとおりです。null
。
Dart では数値はオブジェクトであるため、初期化されていない変数であっても、
数値型には値がありますnull
。
// JavaScript
let name; // == undefined
// Dart
var name; // == null; raises a linter warning
int? x; // == null
で試してみてくださいダーツパッド。
詳細については、次のドキュメントを参照してください。変数。
null またはゼロのチェック
JavaScript では、値 1 または null 以外のオブジェクト
として扱われますtrue
を使用するとき==
比較演算子。
// JavaScript
let myNull = null;
if (!myNull) {
console.log('null is treated as false');
}
let zero = 0;
if (!zero) {
console.log('0 is treated as false');
}
Dart ではブール値のみtrue
は真として扱われます。
/// Dart
var myNull;
var zero = 0;
if (zero == 0) {
print('use "== 0" to check zero');
}
で試してみてくださいダーツパッド。
機能
Dart と JavaScript の関数は一般的に似ています。 主な違いは宣言です。
// JavaScript
function fn() {
return true;
}
/// Dart
/// You can explicitly define the return type.
bool fn() {
return true;
}
で試してみてくださいダーツパッド。
詳細については、次のドキュメントを参照してください。機能。
非同期プログラミング
先物
JavaScript と同様に、Dart はシングルスレッド実行をサポートしています。 JavaScriptでは、 Promise オブジェクトは最終的な完了 (または失敗) を表します。 非同期操作とその結果の値。
ダーツの使い方Future
これを処理するオブジェクト。
// JavaScript
class Example {
_getIPAddress() {
const url = 'https://httpbin.org/ip';
return fetch(url)
.then(response => response.json())
.then(responseJson => {
const ip = responseJson.origin;
return ip;
});
}
}
function main() {
const example = new Example();
example
._getIPAddress()
.then(ip => console.log(ip))
.catch(error => console.error(error));
}
main();
/// Dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class Example {
Future<String> _getIPAddress() {
final url = Uri.https('httpbin.org', '/ip');
return http.get(url).then((response) {
String ip = jsonDecode(response.body)['origin'];
return ip;
});
}
}
void main() {
final example = Example();
example
._getIPAddress()
.then((ip) => print(ip))
.catchError((error) => print(error));
}
詳細については、次のドキュメントを参照してください。Future
オブジェクト。
async
とawait
のasync
関数宣言は非同期関数を定義します。
JavaScript では、async
関数は次の値を返しますPromise
。
のawait
演算子は待機するために使用されます。Promise
。
// JavaScript
class Example {
async function _getIPAddress() {
const url = 'https://httpbin.org/ip';
const response = await fetch(url);
const json = await response.json();
const data = json.origin;
return data;
}
}
async function main() {
const example = new Example();
try {
const ip = await example._getIPAddress();
console.log(ip);
} catch (error) {
console.error(error);
}
}
main();
ダーツでは、async
関数は次の値を返しますFuture
、
関数の本体は後で実行されるようにスケジュールされます。
のawait
演算子は待機するために使用されます。Future
。
// Dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class Example {
Future<String> _getIPAddress() async {
final url = Uri.https('httpbin.org', '/ip');
final response = await http.get(url);
String ip = jsonDecode(response.body)['origin'];
return ip;
}
}
/// An async function returns a `Future`.
/// It can also return `void`, unless you use
/// the `avoid_void_async` lint. In that case,
/// return `Future<void>`.
void main() async {
final example = Example();
try {
final ip = await example._getIPAddress();
print(ip);
} catch (error) {
print(error);
}
}
詳細については、次のドキュメントを参照してください。非同期で待機する。
基礎
Flutter アプリを作成するにはどうすればよいですか?
React Native を使用してアプリを作成するには、
あなたは走るでしょうcreate-react-native-app
コマンドラインから。
$ create-react-native-app <projectname>
Flutter でアプリを作成するには、次のいずれかを実行します。
- Flutter プラグインと Dart プラグインがインストールされた IDE を使用します。
- 使用
flutter create
コマンドラインからコマンドを実行します。ことを確認してください。 Flutter SDK は PATH にあります。
$ flutter create <projectname>
詳細については、を参照してください。入門、 どれの ボタンクリックカウンターアプリの作成手順を説明します。 Flutter プロジェクトを作成すると、必要なすべてのファイルがビルドされます。 Android デバイスと iOS デバイスの両方でサンプル アプリを実行する必要があります。
アプリを実行するにはどうすればよいですか?
React Native では、次のように実行します。npm run
またyarn run
プロジェクトから
ディレクトリ。
Flutter アプリはいくつかの方法で実行できます。
- Flutter プラグインと Dart プラグインを備えた IDE で「run」オプションを使用します。
- 使用
flutter run
プロジェクトのルートディレクトリから。
アプリは接続されたデバイス、iOS シミュレーター上で実行されます。 またはAndroidエミュレータ。
詳細については、「 flutter」を参照してください。入門ドキュメンテーション。
ウィジェットをインポートするにはどうすればよいですか?
React Native では、必要な各コンポーネントをインポートする必要があります。
// React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
Flutter でマテリアル デザイン ライブラリのウィジェットを使用するには、
をインポートするmaterial.dart
パッケージ。 iOS スタイルのウィジェットを使用するには、
クパチーノ図書館をインポートします。より基本的なウィジェット セットを使用するには、
ウィジェットライブラリをインポートします。
または、独自のウィジェット ライブラリを作成してインポートすることもできます。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:my_widgets/my_widgets.dart';
どのウィジェット パッケージをインポートしても、 Dart は、アプリで使用されているウィジェットのみを取り込みます。
詳細については、「Flutter ウィジェット カタログ。
React Native の「Hello world!」に相当するものは何ですか? Flutterのアプリ?
React Native では、HelloWorldApp
クラスが拡張するReact.Component
と
ビューコンポーネントを返すことによって render メソッドを実装します。
// React Native
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
const App = () => {
return (
<View style={styles.container}>
<Text>Hello world!</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});
export default App;
Flutter では、まったく同じ「Hello world!」を作成できます。を使用するアプリCenter
とText
コア ウィジェット ライブラリからのウィジェット。
のCenter
ウィジェットはウィジェット ツリーのルートとなり、1 つの子を持ちます。
のText
ウィジェット。
/// Flutter
import 'package:flutter/material.dart';
void main() {
runApp(
const Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
次の画像は、基本的な Flutter の Android および iOS UI を示しています。 "こんにちは世界!"アプリ。
最も基本的な Flutter アプリを見てきたので、次のセクションではその方法を示します。 Flutter の豊富なウィジェット ライブラリを活用して、モダンで洗練されたウィジェット ライブラリを作成します。 アプリ。
ウィジェットを使用し、それらをネストしてウィジェット ツリーを形成するにはどうすればよいですか?
Flutter では、ほとんどすべてがウィジェットです。
ウィジェットは、アプリのユーザー インターフェイスの基本的な構成要素です。 ウィジェットをウィジェット ツリーと呼ばれる階層に構成します。 各ウィジェットは親ウィジェット内にネストされます そしてその親からプロパティを継承します。 アプリケーション オブジェクト自体もウィジェットです。 個別の「アプリケーション」オブジェクトはありません。 代わりに、ルート ウィジェットがこの役割を果たします。
ウィジェットでは以下を定義できます。
- ボタンやメニューなどの構造要素
- フォントや配色などの文体要素
- レイアウトの側面 - パディングや配置など
次の例は、「Hello world!」を示しています。のウィジェットを使用するアプリ
マテリアルライブラリ。この例では、ウィジェット ツリーはMaterialApp
ルートウィジェット。
/// Flutter
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
),
body: const Center(
child: Text('Hello world'),
),
),
);
}
}
次の画像は「Hello world!」を示しています。マテリアル デザイン ウィジェットから構築されています。 基本的な「Hello world!」よりも多くの機能を無料で利用できます。アプリ。
アプリを作成するときは、次の 2 種類のウィジェットを使用します。StatelessWidget
またStatefulWidget
。
あStatelessWidget
それはまさにそのように聞こえます—
状態のないウィジェット。あStatelessWidget
一度作成されると、
そしてその姿は決して変わりません。
あStatefulWidget
データに基づいて状態を動的に変更する
受信したもの、またはユーザー入力。
ステートレスとステートフルの重要な違い
ウィジェットはそれですStatefulWidget
は持っていますState
物体
状態データを保存し、それを引き継ぐ
ツリー全体が再構築されるため、失われることはありません。
シンプルまたは基本的なアプリでは、ウィジェットを簡単にネストできます。 しかし、コードベースが大きくなり、アプリが複雑になるにつれて、 深くネストされたウィジェットを分割する必要があります ウィジェットまたはより小さなクラスを返す関数。 個別の関数の作成 ウィジェットを使用すると、アプリ内でコンポーネントを再利用できます。
再利用可能なコンポーネントを作成するにはどうすればよいですか?
React Native では、クラスを定義して
再利用可能なコンポーネントを使用してくださいprops
設定する方法
または、選択した要素のプロパティと値を返します。
以下の例では、CustomCard
クラスが定義されている
そして親クラス内で使用されます。
// React Native
const CustomCard = ({ index, onPress }) => {
return (
<View>
<Text> Card {index} </Text>
<Button
title="Press"
onPress={() => onPress(index)}
/>
</View>
);
};
// Usage
<CustomCard onPress={this.onPress} index={item.key} />
Flutter で、カスタム ウィジェットを作成するクラスを定義し、
ウィジェット。を返す関数を定義して呼び出すこともできます。
に示すように再利用可能なウィジェットbuild
次の例の関数。
/// Flutter
class CustomCard extends StatelessWidget {
const CustomCard({
super.key,
required this.index,
required this.onPress,
});
final int index;
final void Function() onPress;
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: <Widget>[
Text('Card $index'),
TextButton(
onPressed: onPress,
child: const Text('Press'),
),
],
));
}
}
class UseCard extends StatelessWidget {
const UseCard({super.key, required this.index});
final int index;
@override
Widget build(BuildContext context) {
/// Usage
return CustomCard(
index: index,
onPress: () {
print('Card $index');
},
);
}
}
前の例では、CustomCard
クラスは Dart の中括弧構文を使用します{ }
示す名前付きパラメータ。
これらのフィールドを必須にするには、次の中括弧を削除します。
コンストラクター、または追加required
コンストラクターに。
次のスクリーンショットは、再利用可能なファイルの例を示しています。CustomCard
クラス。
プロジェクトの構造とリソース
コードはどこから書き始めればよいでしょうか?
から始めてくださいlib/main.dart
ファイル。
Flutter アプリを作成すると自動生成されます。
// Dart
void main() {
print('Hello, this is the main function.');
}
Flutter では、エントリ ポイント ファイルは次のとおりです。{project_name}/lib/main.dart
そして実行
から始まりますmain
関数。
Flutter アプリではファイルはどのように構造化されていますか?
新しい Flutter プロジェクトを作成すると、 次のディレクトリ構造を構築します。 後でカスタマイズすることもできますが、ここから始めます。
┬
└ project_name
┬
├ android - Contains Android-specific files.
├ build - Stores iOS and Android build files.
├ ios - Contains iOS-specific files.
├ lib - Contains externally accessible Dart source files.
┬
└ src - Contains additional source files.
└ main.dart - The Flutter entry point and the start of a new app.
This is generated automatically when you create a Flutter
project.
It's where you start writing your Dart code.
├ test - Contains automated test files.
└ pubspec.yaml - Contains the metadata for the Flutter app.
This is equivalent to the package.json file in React Native.
リソースや資産をどこに置き、どのように使用すればよいですか?
Flutter リソースまたはアセットは、バンドルされてデプロイされるファイルです アプリに組み込まれており、実行時にアクセスできます。 Flutter アプリには次のアセット タイプを含めることができます。
- JSONファイルなどの静的データ
- 設定ファイル
- アイコンと画像 (JPEG、PNG、GIF、アニメーション GIF、WebP、アニメーション WebP、BMP、 および WBMP)
flutterはpubspec.yaml
ファイル、
プロジェクトのルートにあり、
アプリに必要なアセットを特定します。
flutter:
assets:
- assets/my_icon.png
- assets/background.png
のassets
サブセクションでは、アプリに含める必要があるファイルを指定します。
各アセットは明示的なパスによって識別されます
に比べてpubspec.yaml
ファイル。アセットファイルが置かれている場所。
資産を宣言する順序は重要ではありません。
実際に使用されるディレクトリ (assets
この場合)は関係ありません。
ただし、アセットは任意のアプリ ディレクトリに配置できますが、
に配置するベストプラクティスassets
ディレクトリ。
ビルド中に、Flutter はアセットを特別なアーカイブに配置します
と呼ばれるアセットバンドル、アプリが実行時に読み取るもの。
アセットのパスがアセットのセクションで指定されている場合pubspec.yaml
、
ビルドプロセスはファイルを探します
隣接するサブディレクトリに同じ名前が付けられています。
これらのファイルはアセット バンドルにも含まれています
指定されたアセットとともに。 Flutter はアセット バリアントを使用します
アプリに適切な解像度の画像を選択するとき。
React Native では、画像ファイルを配置して静的画像を追加します。 ソースコードディレクトリ内にあり、それを参照しています。
<Image source={require('./my-icon.png')} />
// OR
<Image
source={{
url: 'https://reactnative.dev/img/tiny_logo.png'
}}
/>
Flutter でアプリに静的画像を追加します
を使用してImage.asset
ウィジェットのビルドメソッドのコンストラクター。
Image.asset('assets/background.png');
詳細については、を参照してください。Flutter でのアセットと画像の追加。
ネットワーク経由で画像をロードするにはどうすればよいですか?
React Native では、次のように指定します。uri
の中にsource
の小道具Image
コンポーネントを提供し、
必要に応じてサイズを変更します。
Flutter では、Image.network
含めるコンストラクター
URLからの画像。
Image.network('https://docs.flutter.dev/assets/images/docs/owl.jpg');
パッケージとパッケージ プラグインをインストールするにはどうすればよいですか?
Flutter は、他の開発者が提供した共有パッケージの使用をサポートしています。 Flutter と Dart のエコシステム。これにより、何もせずにアプリを迅速に構築できます。 すべてをゼロから開発する必要があります。含まれるパッケージ プラットフォーム固有のコードは、パッケージ プラグインとして知られています。
React Native では、次のようにします。yarn add {package-name}
またnpm install --save {package-name}
パッケージをインストールするには
コマンドラインから。
Flutter で、次の手順に従ってパッケージをインストールします。
- 追加するには、
google_sign_in
パッケージを依存関係として実行しますflutter pub add
:
$ flutter pub add google_sign_in
- コマンドラインから次のようにパッケージをインストールします。
flutter pub get
。 IDE を使用している場合は、頻繁に実行されます。flutter pub get
あなたにとって、あるいはそうかもしれない そうするように促します。 - 以下に示すように、パッケージをアプリコードにインポートします。
import 'package:flutter/material.dart';
詳細については、を参照してください。パッケージの使用とパッケージとプラグインの開発。
Flutter 開発者によって共有されている多くのパッケージは、 flutterパッケージのセクションパブ.dev。
flutterウィジェット
Flutter では、ビューを説明するウィジェットから UI を構築します。 現在の構成と状態を考慮すると、次のようになります。
多くの場合、ウィジェットは多数の小さな要素で構成されます。
強力な効果を生み出すためにネストされた単一目的のウィジェット。
たとえば、Container
ウィジェットは次のもので構成されます
レイアウト、ペイント、位置決め、サイズ変更を担当するいくつかのウィジェット。
具体的には、Container
ウィジェットには以下が含まれますLimitedBox
、ConstrainedBox
、Align
、Padding
、DecoratedBox
、 とTransform
ウィジェット。
サブクラス化ではなくContainer
カスタマイズされた効果を生成するには、次のことができます。
これらやその他のシンプルなウィジェットを新しくユニークな方法で作成します。
のCenter
ウィジェットは、レイアウトを制御する方法のもう 1 つの例です。
ウィジェットを中央に配置するには、ウィジェットをCenter
ウィジェットを選択してレイアウトを使用する
配置、行、列、グリッド用のウィジェット。
これらのレイアウト ウィジェットには、独自の視覚的表現がありません。
代わりに、その唯一の目的は、別のシステムのある側面を制御することです。
ウィジェットのレイアウト。ウィジェットがなぜレンダリングされるのかを理解するには、
ある意味、隣接するウィジェットを検査すると役立つことがよくあります。
詳細については、「Flutterの技術概要。
コア ウィジェットの詳細については、Widgets
パッケージ、
見るFlutter基本ウィジェット、
のFlutter ウィジェット カタログ、
または flutterウィジェットインデックス。
ビュー
View
容器?
と同等のものは何ですかリアクトネイティブでは、View
レイアウトをサポートするコンテナですFlexbox
、
スタイル、タッチ操作、アクセシビリティ コントロール。
Flutter では、コア レイアウト ウィジェットをWidgets
図書館などContainer
、Column
、Row
、 とCenter
。
詳細については、「レイアウトウィジェットカタログ。
FlatList
またSectionList
?
と同等のものは何ですかあList
垂直方向に配置されたコンポーネントのスクロール可能なリストです。
リアクトネイティブでは、FlatList
またSectionList
単純なレンダリングに使用されるか、
セクション化されたリスト。
// React Native
<FlatList
data={[ ... ]}
renderItem={({ item }) => <Text>{item.key}</Text>}
/>
ListView
Flutter で最もよく使用されるスクロール ウィジェットです。
デフォルトのコンストラクターは、子の明示的なリストを受け取ります。ListView
少数のウィジェットに最適です。
大規模なリストまたは無限のリストの場合は、次を使用します。ListView.builder
、
要求に応じて子を構築し、構築するだけです
目に見えるあの子たち。
var data = [
'Hello',
'World',
];
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return Text(data[index]);
},
);
無限スクロールリストを実装する方法については、公式を参照してください。infinite_list
サンプル。
Canvas を使用して描画またはペイントするにはどうすればよいですか?
React Native にはキャンバス コンポーネントが存在しません
したがって、サードパーティのライブラリは次のようになりますreact-native-canvas
使用されています。
// React Native
const CanvasComp = () => {
const handleCanvas = (canvas) => {
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'skyblue';
ctx.beginPath();
ctx.arc(75, 75, 50, 0, 2 * Math.PI);
ctx.fillRect(150, 100, 300, 300);
ctx.stroke();
};
return (
<View>
<Canvas ref={this.handleCanvas} />
</View>
);
}
Flutter では、CustomPaint
とa31カフェ1-a32b-4beb-a1ea-cd6364b00629キャンバスに描画するクラス。
次の例は、ペイント フェーズ中にCustomPaint
ウィジェット。抽象クラスを実装します。CustomPainter
、
そしてそれを渡しますCustomPaint
の画家の所有物。CustomPaint
サブクラスは以下を実装する必要がありますpaint()
とshouldRepaint()
方法。
class MyCanvasPainter extends CustomPainter {
const MyCanvasPainter();
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()..color = Colors.amber;
canvas.drawCircle(const Offset(100, 200), 40, paint);
final Paint paintRect = Paint()..color = Colors.lightBlue;
final Rect rect = Rect.fromPoints(
const Offset(150, 300),
const Offset(300, 400),
);
canvas.drawRect(rect, paintRect);
}
@override
bool shouldRepaint(MyCanvasPainter oldDelegate) => false;
}
class MyCanvasWidget extends StatelessWidget {
const MyCanvasWidget({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: CustomPaint(painter: MyCanvasPainter()),
);
}
}
レイアウト
ウィジェットを使用してレイアウト プロパティを定義するにはどうすればよいですか?
React Native では、ほとんどのレイアウトは props を使用して実行できます。
特定のコンポーネントに渡されます。
たとえば、次のように使用できます。style
上のプロップView
成分
フレックスボックスのプロパティを指定するため。
コンポーネントを列に配置するには、次のような prop を指定します。flexDirection: 'column'
。
// React Native
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'center'
}}
>
Flutter では、レイアウトは主にウィジェットによって定義されます レイアウトを提供するために特別に設計された、 コントロール ウィジェットとそのスタイル プロパティを組み合わせます。
たとえば、Column
とRow
ウィジェット
子の配列を取得して整列させます
それぞれ縦と横。
あContainer
ウィジェットには次の組み合わせが必要です
レイアウトとスタイルのプロパティ、およびCenter
ウィジェットはその子ウィジェットを中心に配置します。
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: <Widget>[
Container(
color: Colors.red,
width: 100,
height: 100,
),
Container(
color: Colors.blue,
width: 100,
height: 100,
),
Container(
color: Colors.green,
width: 100,
height: 100,
),
],
),
);
Flutter は、コア ウィジェット ライブラリでさまざまなレイアウト ウィジェットを提供します。
例えば、Padding
、Align
、 とStack
。
完全なリストについては、を参照してください。レイアウトウィジェット。
ウィジェットを階層化するにはどうすればよいですか?
React Native では、次を使用してコンポーネントを階層化できます。absolute
ポジショニング。
flutterはStack
子ウィジェットをレイヤーに配置するウィジェット。
ウィジェットは、ベース ウィジェットと完全にまたは部分的に重なることができます。
のStack
ウィジェットは、ボックスの端を基準にして子を配置します。
このクラスは、単に複数の子ウィジェットを重ねたい場合に便利です。
@override
Widget build(BuildContext context) {
return Stack(
alignment: const Alignment(0.6, 0.6),
children: <Widget>[
const CircleAvatar(
backgroundImage: NetworkImage(
'https://avatars3.githubusercontent.com/u/14101776?v=4',
),
),
Container(
color: Colors.black45,
child: const Text('Flutter'),
),
],
);
前の例では、Stack
コンテナをオーバーレイするには
(それを表示しますText
半透明の黒い背景に)
の上にCircleAvatar
。
スタックは、配置プロパティを使用してテキストをオフセットします。
とAlignment
コーディネート。
詳細については、「Stack
クラスのドキュメント。
スタイリング
コンポーネントのスタイルを設定するにはどうすればよいですか?
React Native では、インライン スタイルとstylesheets.create
コンポーネントのスタイルを設定するために使用されます。
// React Native
<View style={styles.container}>
<Text style={{ fontSize: 32, color: 'cyan', fontWeight: '600' }}>
This is a sample text
</Text>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
});
Flutter では、Text
ウィジェットはTextStyle
クラス
スタイルプロパティの場合。同じテキストを使用したい場合
複数の場所にスタイルを作成することができます。TextStyle
クラスにして複数の用途に使用するText
ウィジェット。
const TextStyle textStyle = TextStyle(
color: Colors.cyan,
fontSize: 32,
fontWeight: FontWeight.w600,
);
return const Center(
child: Column(
children: <Widget>[
Text('Sample text', style: textStyle),
Padding(
padding: EdgeInsets.all(20),
child: Icon(
Icons.lightbulb_outline,
size: 48,
color: Colors.redAccent,
),
),
],
),
);
Icons
とColors
?
使い方React Native にはアイコンのサポートが含まれていません そのため、サードパーティのライブラリが使用されます。
Flutter では、マテリアル ライブラリをインポートすると、 の豊富なセットマテリアルアイコンと色。
return const Icon(Icons.lightbulb_outline, color: Colors.redAccent);
を使用するときは、Icons
クラス、
必ず設定してくださいuses-material-design: true
の
プロジェクトのpubspec.yaml
ファイル。
これにより、MaterialIcons
フォント、
アイコンを表示するツールはアプリに含まれています。
一般に、マテリアル ライブラリを使用する場合は、
この行を含める必要があります。
name: my_awesome_application
flutter:
uses-material-design: true
flutterズクパチーノ (iOS スタイル)パッケージは高い
現在の iOS デザイン言語に忠実なウィジェット。
を使用するには、CupertinoIcons
フォント、
依存関係を追加しますcupertino_icons
あなたのプロジェクトの中でpubspec.yaml
ファイル。
name: my_awesome_application
dependencies:
cupertino_icons: ^0.1.0
コンポーネントの色とスタイルをグローバルにカスタマイズするには、
使用ThemeData
デフォルトの色を指定するには
テーマのさまざまな側面について。
テーマのプロパティを設定しますMaterialApp
にThemeData
物体。
のColors
クラスは色を提供します
マテリアルデザインからカラーパレット。
次の例では、プライマリ スウォッチを次のように設定します。blue
そしてテキストの選択はred
。
class SampleApp extends StatelessWidget {
const SampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample App',
theme: ThemeData(
primarySwatch: Colors.blue,
textSelectionTheme:
const TextSelectionThemeData(selectionColor: Colors.red)),
home: const SampleAppPage(),
);
}
}
スタイルテーマを追加するにはどうすればよいですか?
React Native では、共通のテーマが定義されています。 コンポーネントをスタイルシートに追加し、コンポーネントで使用します。
Flutter では、ほぼすべてのものに対して均一なスタイルを作成します
でスタイルを定義することで、ThemeData
クラスを作成し、それをテーマのプロパティに渡します。MaterialApp
ウィジェット。
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.cyan,
brightness: Brightness.dark,
),
home: const StylingPage(),
);
}
あTheme
を使用しなくても適用できますMaterialApp
ウィジェット。
のTheme
ウィジェットはThemeData
その中でdata
パラメータ
そして、ThemeData
すべての子ウィジェットに。
@override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
primaryColor: Colors.cyan,
brightness: brightness,
),
child: Scaffold(
backgroundColor: Theme.of(context).primaryColor,
//...
),
);
}
状態管理
状態は同期的に読み取ることができる情報です
ウィジェットの構築時または情報
それはウィジェットの存続期間中に変更される可能性があります。
Flutter でアプリの状態を管理するには、
使うStatefulWidget
State オブジェクトとペアになります。
Flutter で状態を管理する方法の詳細については、 見る状態管理。
ステートレスウィジェット
あStatelessWidget
Flutter ではウィジェットです
状態を変更する必要はありません。
管理する内部状態はありません。
ステートレス ウィジェットは、ユーザー インターフェイスの一部である場合に便利です。
あなたが説明しているのは、
オブジェクト自体の構成情報と、BuildContext
ここではウィジェットがインフレートされています。
AboutDialog
、CircleAvatar
、 とText
例です
サブクラス化するステートレス ウィジェットの数StatelessWidget
。
import 'package:flutter/material.dart';
void main() => runApp(
const MyStatelessWidget(
text: 'StatelessWidget Example to show immutable data',
),
);
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({
super.key,
required this.text,
});
final String text;
@override
Widget build(BuildContext context) {
return Center(
child: Text(
text,
textDirection: TextDirection.ltr,
),
);
}
}
前の例では、次のコンストラクターを使用しています。MyStatelessWidget
合格するクラスtext
としてマークされています。final
。
このクラスは拡張されますStatelessWidget
— 不変のデータが含まれています。
のbuild
通常、ステートレス ウィジェットのメソッドが呼び出されます。
たった 3 つの状況の場合:
- ウィジェットがツリーに挿入されるとき
- ウィジェットの親がその構成を変更したとき
- とき
InheritedWidget
それは依存する、変化する
ステートフルウィジェット
あStatefulWidget
状態を変更するウィジェットです。
使用setState
を管理する方法
状態が変化するStatefulWidget
。
への電話setState()
flutterに告げる
状態に何かが変化したという枠組み、
これにより、アプリはbuild()
方法
アプリが変更を反映できるようにします。
州ウィジェット作成時に同期的に読み込める情報です
構築され、ウィジェットの存続期間中に変更される可能性があります。
それを保証するのはウィジェット実装者の責任です。
状態が変化すると、状態オブジェクトに即座に通知されます。
使用StatefulWidget
ウィジェットが動的に変更できる場合。
たとえば、フォームに入力するとウィジェットの状態が変化します。
またはスライダーを移動します。
または、時間の経過とともに変化する可能性があります。おそらく、データ フィードによって UI が更新されます。
Checkbox
、Radio
、Slider
、InkWell
、Form
、 とTextField
サブクラス化するステートフル ウィジェットの例です。StatefulWidget
。
次の例では、StatefulWidget
それにはcreateState()
方法。
このメソッドは、ウィジェットの状態を管理する状態オブジェクトを作成します。_MyStatefulWidgetState
。
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({
super.key,
required this.title,
});
final String title;
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
次の状態クラス、_MyStatefulWidgetState
、
を実装しますbuild()
ウィジェットのメソッド。
ユーザーが切り替えたときなど、状態が変化したとき
ボタン、setState()
新しいトグル値を使用して呼び出されます。
これにより、フレームワークは UI でこのウィジェットを再構築します。
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool showText = true;
bool toggleState = true;
Timer? t2;
void toggleBlinkState() {
setState(() {
toggleState = !toggleState;
});
if (!toggleState) {
t2 = Timer.periodic(const Duration(milliseconds: 1000), (t) {
toggleShowText();
});
} else {
t2?.cancel();
}
}
void toggleShowText() {
setState(() {
showText = !showText;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
if (showText)
const Text(
'This execution will be done before you can blink.',
),
Padding(
padding: const EdgeInsets.only(top: 70),
child: ElevatedButton(
onPressed: toggleBlinkState,
child: toggleState
? const Text('Blink')
: const Text('Stop Blinking'),
),
),
],
),
),
);
}
}
StatefulWidget と StatelessWidget のベスト プラクティスは何ですか?
ウィジェットを設計する際に考慮すべき点がいくつかあります。
- ウィジェットを次のようにするかどうかを決定します。
ある
StatefulWidget
またはStatelessWidget
。
Flutter では、ウィジェットはステートフルかステートレスのいずれかになります。 それらは状態の変化に依存します。
- ウィジェットが変更された場合、ユーザーがウィジェットを操作するか、 データフィードが UI を中断すると、ステートフル。
- ウィジェットがfinalまたはimmutableの場合、それはステートレス。
- どのオブジェクトがウィジェットの状態を管理するかを決定します (
StatefulWidget
)。
Flutter では、状態を管理する主な方法が 3 つあります。
- ウィジェットは独自の状態を管理します
- 親ウィジェットはウィジェットの状態を管理します
- 組み合わせて使用するアプローチ
どのアプローチを使用するかを決定するときは、次の原則を考慮してください。
- 問題の状態がユーザーデータの場合、 たとえば、チェックボックスのオンまたはオフのモード、 またはスライダーの位置の場合、状態を最も適切に管理できます。 親ウィジェットによって。
- 問題の状態が美的である場合、たとえばアニメーションの場合、 その場合、ウィジェット自体が状態を最適に管理します。
- 疑わしい場合は、親ウィジェットに子ウィジェットの状態を管理させてください。
- StatefulWidget と State をサブクラス化します。
のMyStatefulWidget
クラスはそれ自体の状態を管理し、拡張しますStatefulWidget
、それはオーバーライドしますcreateState()
を作成する方法State
物体、
そしてフレームワークは呼び出しますcreateState()
ウィジェットを構築します。
この例では、createState()
のインスタンスを作成します_MyStatefulWidgetState
、 どれの
次のベスト プラクティスで実装されます。
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({
super.key,
required this.title,
});
final String title;
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
//...
}
}
- StatefulWidget をウィジェット ツリーに追加します。
カスタムを追加StatefulWidget
ウィジェットツリーへ
アプリのビルドメソッド内。
class MyStatelessWidget extends StatelessWidget {
// This widget is the root of your application.
const MyStatelessWidget({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyStatefulWidget(title: 'State Change Demo'),
);
}
}
小道具
React Native では、ほとんどのコンポーネントをカスタマイズできます。
と呼ばれる、さまざまなパラメータまたはプロパティを使用して作成されます。props
。
これらのパラメータは、次を使用して子コンポーネントで使用できます。this.props
。
// React Native
const CustomCard = ({ index, onPress }) => {
return (
<View>
<Text> Card {index} </Text>
<Button
title='Press'
onPress={() => onPress(index)}
/>
</View>
);
};
const App = () => {
const onPress = (index) => {
console.log('Card ', index);
};
return (
<View>
<FlatList
data={[ /* ... */ ]}
renderItem={({ item }) => (
<CustomCard onPress={onPress} index={item.key} />
)}
/>
</View>
);
};
Flutter では、マークされたローカル変数または関数を割り当てます。final
パラメーター化されたコンストラクターで受け取ったプロパティを使用します。
/// Flutter
class CustomCard extends StatelessWidget {
const CustomCard({
super.key,
required this.index,
required this.onPress,
});
final int index;
final void Function() onPress;
@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: <Widget>[
Text('Card $index'),
TextButton(
onPressed: onPress,
child: const Text('Press'),
),
],
));
}
}
class UseCard extends StatelessWidget {
const UseCard({super.key, required this.index});
final int index;
@override
Widget build(BuildContext context) {
/// Usage
return CustomCard(
index: index,
onPress: () {
print('Card $index');
},
);
}
}
ローカルストレージ
大量のデータを保存する必要がなく、保存する必要もない場合
構造、使用できますshared_preferences
これにより、次のことが可能になります
プリミティブ データの永続的なキーと値のペアの読み取りと書き込み
型: ブール値、float、int、long、string。
アプリに対してグローバルな永続的なキーと値のペアを保存するにはどうすればよいですか?
React Native では、setItem
とgetItem
機能
のAsyncStorage
データを保存および取得するコンポーネント
これは永続的であり、アプリに対してグローバルです。
// React Native
const [counter, setCounter] = useState(0)
...
await AsyncStorage.setItem( 'counterkey', json.stringify(++this.state.counter));
AsyncStorage.getItem('counterkey').then(value => {
if (value != null) {
setCounter(value);
}
});
Flutter では、shared_preferences
プラグインから
永続的かつグローバルなキーと値のデータを保存および取得する
アプリに。のshared_preferences
プラグインラップNSUserDefaults
iOS とSharedPreferences
アンドロイドでは、
単純なデータの永続的なストアを提供します。
追加するには、shared_preferences
パッケージを依存関係として実行しますflutter pub add
:
$ flutter pub add shared_preferences
import 'package:shared_preferences/shared_preferences.dart';
永続データを実装するには、セッター メソッドを使用します。
によって提供されるSharedPreferences
クラス。
さまざまなプリミティブに対してセッターメソッドが利用可能
などのタイプsetInt
、setBool
、 とsetString
。
データを読み取るには、提供されている適切なゲッター メソッドを使用します。
によってSharedPreferences
クラス。それぞれについて
setter に対応する getter メソッドがあり、
例えば、getInt
、getBool
、 とgetString
。
Future<void> updateCounter() async {
final prefs = await SharedPreferences.getInstance();
int? counter = prefs.getInt('counter');
if (counter is int) {
await prefs.setInt('counter', ++counter);
}
setState(() {
_counter = counter;
});
}
ルーティング
ほとんどのアプリには、さまざまな画面を表示するための複数の画面が含まれています。 情報の種類。たとえば、次のような製品があるとします。 ユーザーが製品をタップできる画像を表示する画面 画像をクリックすると、新しい画面で製品に関する詳細情報が表示されます。
Android では、新しい画面は新しいアクティビティです。 iOS では、新しい画面は新しい ViewController です。 flutterでは、 画面は単なるウィジェットです。新しいページに移動するには Flutter の画面には、Navigator ウィジェットを使用します。
画面間を移動するにはどうすればよいですか?
React Native には、次の 3 つの主要なナビゲーターがあります。 StackNavigator、TabNavigator、および DrawerNavigator。 それぞれが画面を構成および定義する方法を提供します。
// React Native
const MyApp = TabNavigator(
{ Home: { screen: HomeScreen }, Notifications: { screen: tabNavScreen } },
{ tabBarOptions: { activeTintColor: '#e91e63' } }
);
const SimpleApp = StackNavigator({
Home: { screen: MyApp },
stackScreen: { screen: StackScreen }
});
export default (MyApp1 = DrawerNavigator({
Home: {
screen: SimpleApp
},
Screen2: {
screen: drawerScreen
}
}));
Flutter には、画面間を移動するために使用される 2 つの主要なウィジェットがあります。
- あ
Route
アプリの画面またはページの抽象化です。 - あ
Navigator
ルートを管理するウィジェットです。
あNavigator
子のセットを管理するウィジェットとして定義されます
スタック規律を持つウィジェット。ナビゲーターはスタックを管理します
のRoute
オブジェクトを作成し、スタックを管理するためのメソッドを提供します。
好きNavigator.push
とNavigator.pop
。
ルートのリストは、MaterialApp
ウィジェット、
あるいは、ヒーロー アニメーションなどでその場で構築される場合もあります。
次の例では、名前付きルートを指定します。MaterialApp
ウィジェット。
class NavigationApp extends StatelessWidget {
// This widget is the root of your application.
const NavigationApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
//...
routes: <String, WidgetBuilder>{
'/a': (context) => const UsualNavScreen(),
'/b': (context) => const DrawerNavScreen(),
},
//...
);
}
}
名前付きルートに移動するには、Navigator.of()
メソッドは、を指定するために使用されます。BuildContext
(ウィジェット ツリー内のウィジェットの場所へのハンドル)。
ルートの名前はpushNamed
に機能する
指定したルートに移動します。
Navigator.of(context).pushNamed('/a');
プッシュ方式を使用することもできますNavigator
どれの
与えられたものを追加しますRoute
の歴史に
与えられたものを最もしっかりと囲むナビゲータBuildContext
、
そしてそれに移行します。次の例では、
のMaterialPageRoute
ウィジェットはモーダル ルートです。
画面全体をプラットフォームに適応したものに置き換えます。
遷移。それにはWidgetBuilder
必須パラメータとして。
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const UsualNavScreen(),
),
);
タブ ナビゲーションとドロワー ナビゲーションを使用するにはどうすればよいですか?
マテリアル デザイン アプリには、主に 2 つのオプションがあります Flutter ナビゲーションの場合: タブとドロワー。 タブや引き出しをサポートするスペースが不十分な場合 良い代替案を提供します。
タブナビゲーション
リアクトネイティブでは、createBottomTabNavigator
とTabNavigation
に慣れた
タブの表示とタブ ナビゲーション用。
// React Native
import { createBottomTabNavigator } from 'react-navigation';
const MyApp = TabNavigator(
{ Home: { screen: HomeScreen }, Notifications: { screen: tabNavScreen } },
{ tabBarOptions: { activeTintColor: '#e91e63' } }
);
Flutter は、ドロワーと タブナビゲーション:
TabController
- 間でタブの選択を調整します。
TabBar
そしてTabBarView
。 TabBar
- タブを横一列に表示します。
Tab
- マテリアル デザインの TabBar タブを作成します。
TabBarView
- 現在選択されているタブに対応するウィジェットを表示します。
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late TabController controller = TabController(length: 2, vsync: this);
@override
Widget build(BuildContext context) {
return TabBar(
controller: controller,
tabs: const <Tab>[
Tab(icon: Icon(Icons.person)),
Tab(icon: Icon(Icons.email)),
],
);
}
}
あTabController
タブの選択を調整するために必要です
の間TabBar
そしてTabBarView
。
のTabController
コンストラクタlength
引数は合計です
タブの数。あTickerProvider
トリガーするには必要です
フレームが状態変更をトリガーするたびに通知が送信されます。
のTickerProvider
はvsync
。を渡すvsync: this
に対する議論TabController
コンストラクタ
新しいものを作成するたびに、TabController
。
のTickerProvider
実装されたインターフェースです
販売できるクラス別Ticker
オブジェクト。
ティッカーは、通知が必要なオブジェクトであればいつでも使用できます。
フレーム トリガーですが、最も一般的には、AnimationController
。AnimationController
s
必要TickerProvider
彼らのTicker
。
StateからAnimationControllerを作成している場合、
その後、を使用できますTickerProviderStateMixin
またSingleTickerProviderStateMixin
適切なクラスを取得するためのクラスTickerProvider
。
のScaffold
ウィジェットは新しいものをラップしますTabBar
ウィジェットと
2 つのタブを作成します。のTabBarView
ウィジェット
として渡されますbody
のパラメータScaffold
ウィジェット。
に対応するすべての画面TabBar
ウィジェットのタブは
子どもたちへTabBarView
ウィジェットと同じものTabController
。
class _NavigationHomePageState extends State<NavigationHomePage>
with SingleTickerProviderStateMixin {
late TabController controller = TabController(length: 2, vsync: this);
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: Material(
color: Colors.blue,
child: TabBar(
tabs: const <Tab>[
Tab(
icon: Icon(Icons.person),
),
Tab(
icon: Icon(Icons.email),
),
],
controller: controller,
),
),
body: TabBarView(
controller: controller,
children: const <Widget>[HomeScreen(), TabScreen()],
));
}
}
ドロワーナビゲーション
React Nativeでは、必要なreact-navigationパッケージをインポートしてから使用します。createDrawerNavigator
とDrawerNavigation
。
// React Native
export default (MyApp1 = DrawerNavigator({
Home: {
screen: SimpleApp
},
Screen2: {
screen: drawerScreen
}
}));
Flutter では、Drawer
ウィジェットとの組み合わせScaffold
マテリアル デザイン ドロワーを使用してレイアウトを作成します。
を追加するにはDrawer
アプリに追加するには、Scaffold
ウィジェット。
のScaffold
ウィジェットは一貫性を提供します
に続くアプリの視覚的な構造マテリアルデザインガイドライン。もサポートします
特別なマテリアル デザイン コンポーネント、
そのようなDrawers
、AppBars
、 とSnackBars
。
のDrawer
ウィジェットはスライドするマテリアル デザイン パネルです
端から水平にScaffold
ナビゲーションを表示するには
アプリケーション内のリンク。あなたはできる
を提供するElevatedButton
、Text
ウィジェット、
または、その子として表示する項目のリストDrawer
ウィジェット。
次の例では、ListTile
ウィジェットはタップするとナビゲーションを提供します。
@override
Widget build(BuildContext context) {
return Drawer(
elevation: 20,
child: ListTile(
leading: const Icon(Icons.change_history),
title: const Text('Screen2'),
onTap: () {
Navigator.of(context).pushNamed('/b');
},
),
);
}
のScaffold
ウィジェットには、AppBar
自動的に表示されるウィジェット
を表示する適切な IconButton を表示します。Drawer
引き出しがあるとき
で利用可能Scaffold
。のScaffold
自動的に処理します
エッジスワイプジェスチャを表示するには、Drawer
。
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: Drawer(
elevation: 20,
child: ListTile(
leading: const Icon(Icons.change_history),
title: const Text('Screen2'),
onTap: () {
Navigator.of(context).pushNamed('/b');
},
),
),
appBar: AppBar(title: const Text('Home')),
body: Container(),
);
}
ジェスチャー検出とタッチイベント処理
ジェスチャーを聞いて応答するには、 Flutter はタップ、ドラッグ、スケーリングをサポートしています。 Flutter のジェスチャ システムには 2 つの別々のレイヤーがあります。 最初の層には生のポインター イベントが含まれます。 ポインタの位置と動きを記述します。 (タッチ、マウス、スタイラスの動きなど) を画面全体に渡って実行します。 2 番目のレイヤーにはジェスチャが含まれます。 意味論的なアクションを記述する 1 つ以上のポインターの動きで構成されます。
クリックまたはプレスリスナーをウィジェットに追加するにはどうすればよいですか?
React Nativeでは、コンポーネントにリスナーが追加されます
使用してPanResponder
またはTouchable
コンポーネント。
// React Native
<TouchableOpacity
onPress={() => {
console.log('Press');
}}
onLongPress={() => {
console.log('Long Press');
}}
>
<Text>Tap or Long Press</Text>
</TouchableOpacity>
より複雑なジェスチャや複数のタッチを組み合わせる場合
たった一つのジェスチャー、PanResponder
使用されている。
// React Native
const App = () => {
const panResponderRef = useRef(null);
useEffect(() => {
panResponderRef.current = PanResponder.create({
onMoveShouldSetPanResponder: (event, gestureState) =>
!!getDirection(gestureState),
onPanResponderMove: (event, gestureState) => true,
onPanResponderRelease: (event, gestureState) => {
const drag = getDirection(gestureState);
},
onPanResponderTerminationRequest: (event, gestureState) => true
});
}, []);
return (
<View style={styles.container} {...panResponderRef.current.panHandlers}>
<View style={styles.center}>
<Text>Swipe Horizontally or Vertically</Text>
</View>
</View>
);
};
Flutter でクリック (またはプレス) リスナーをウィジェットに追加するには、
ボタンまたはタッチ可能なウィジェットを使用します。onPress: field
。
または、ウィジェットをラップしてジェスチャ検出をウィジェットに追加します
でGestureDetector
。
@override
Widget build(BuildContext context) {
return GestureDetector(
child: Scaffold(
appBar: AppBar(title: const Text('Gestures')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Tap, Long Press, Swipe Horizontally or Vertically'),
],
)),
),
onTap: () {
print('Tapped');
},
onLongPress: () {
print('Long Pressed');
},
onVerticalDragEnd: (value) {
print('Swiped Vertically');
},
onHorizontalDragEnd: (value) {
print('Swiped Horizontally');
},
);
}
リストなどの詳細については、
flutterGestureDetector
コールバック、
を参照してくださいGestureDetector クラス。
HTTPネットワークリクエストの実行
インターネットからデータを取得することは、ほとんどのアプリで一般的です。そして flutterでは、
のhttp
パッケージは、インターネットからデータを取得する最も簡単な方法を提供します。
API 呼び出しからデータを取得するにはどうすればよいですか?
React Native はネットワーク用の Fetch API を提供します。フェッチ リクエストを作成します。 そして、データを取得するための応答を受信します。
// React Native
const [ipAddress, setIpAddress] = useState('')
const _getIPAddress = () => {
fetch('https://httpbin.org/ip')
.then(response => response.json())
.then(responseJson => {
setIpAddress(responseJson.origin);
})
.catch(error => {
console.error(error);
});
};
flutterはhttp
パッケージ。
追加するには、http
パッケージを依存関係として実行しますflutter pub add
:
$ flutter pub add http
flutterはdart:io
コア HTTP サポート クライアント。
HTTP クライアントを作成するには、インポートしますdart:io
。
import 'dart:io';
クライアントは次の HTTP 操作をサポートします。 取得、投稿、配置、および削除。
final url = Uri.parse('https://httpbin.org/ip');
final httpClient = HttpClient();
Future<void> getIPAddress() async {
final request = await httpClient.getUrl(url);
final response = await request.close();
final responseBody = await response.transform(utf8.decoder).join();
final String ip = jsonDecode(responseBody)['origin'];
setState(() {
_ipAddress = ip;
});
}
フォーム入力
テキスト フィールドを使用すると、ユーザーはアプリにテキストを入力できるようになります。
フォーム、メッセージング アプリ、検索エクスペリエンスなどの構築に使用されます。
Flutter は 2 つのコア テキスト フィールド ウィジェットを提供します。TextField
とTextFormField
。
テキストフィールドウィジェットを使用するにはどうすればよいですか?
React Native では、テキストを入力するにはTextInput
テキストを表示するコンポーネント
入力ボックスに入力し、コールバックを使用して値を変数に保存します。
// React Native
const [password, setPassword] = useState('')
...
<TextInput
placeholder="Enter your Password"
onChangeText={password => setPassword(password)}
/>
<Button title="Submit" onPress={this.validate} />
Flutter では、TextEditingController
を管理するクラスTextField
ウィジェット。
テキストフィールドが変更されるたびに、
コントローラーはリスナーに通知します。
リスナーはテキストと選択プロパティを読み取って、
ユーザーがフィールドに入力した内容を学習します。
テキストにアクセスできますTextField
によってtext
コントローラーのプロパティ。
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Column(children: [
TextField(
controller: _controller,
decoration: const InputDecoration(
hintText: 'Type something',
labelText: 'Text Field',
),
),
ElevatedButton(
child: const Text('Submit'),
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Alert'),
content: Text('You typed ${_controller.text}'),
);
});
},
),
]);
}
この例では、ユーザーが送信ボタンをクリックすると、警告ダイアログが表示されます。
テキストフィールドに入力されている現在のテキストを表示します。
これは、AlertDialog
警告メッセージとそのテキストを表示するウィジェット
のTextField
によってアクセスされます料金5ba24-b834-44b9-b2ee-985254116592の財産TextEditingController
。
フォーム ウィジェットを使用するにはどうすればよいですか?
Flutter では、Form
ウィジェットどこTextFormField
ウィジェットと送信
ボタンは子として渡されます。
のTextFormField
ウィジェットには次のパラメータがありますonSaved
コールバックを受け取って実行します
フォームを保存したとき。あFormState
オブジェクトは保存、リセット、または検証に使用されます
各FormField
それはこの子孫ですForm
。
を取得するには、FormState
、使用できますForm.of()
を祖先とするコンテキストを持つForm
、
または渡すGlobalKey
にForm
コンストラクターと呼び出しGlobalKey.currentState()
。
@override
Widget build(BuildContext context) {
return Form(
key: formKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) {
if (value != null && value.contains('@')) {
return null;
}
return 'Not a valid email.';
},
onSaved: (val) {
_email = val;
},
decoration: const InputDecoration(
hintText: 'Enter your email',
labelText: 'Email',
),
),
ElevatedButton(
onPressed: _submit,
child: const Text('Login'),
),
],
),
);
}
次の例は、その方法を示していますForm.save()
とformKey
(これはGlobalKey
)、送信時にフォームを保存するために使用されます。
void _submit() {
final form = formKey.currentState;
if (form != null && form.validate()) {
form.save();
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Alert'),
content: Text('Email: $_email, password: $_password'));
},
);
}
}
プラットフォーム固有のコード
クロスプラットフォーム アプリを構築するときは、できるだけ多くのコードを再利用したいと考えます。 プラットフォーム間で可能です。ただし、次のようなシナリオが発生する可能性があります。 OS によってコードが異なるのは当然です。 これには、特定のプラットフォームを宣言して個別に実装する必要があります。
React Native では、次の実装が使用されます。
// React Native
if (Platform.OS === 'ios') {
return 'iOS';
} else if (Platform.OS === 'android') {
return 'android';
} else {
return 'not recognised';
}
Flutter では、次の実装を使用します。
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.iOS) {
return 'iOS';
}
if (platform == TargetPlatform.android) {
return 'android';
}
if (platform == TargetPlatform.fuchsia) {
return 'fuchsia';
}
return 'not recognized ';
デバッグ
Flutter でアプリをデバッグするにはどのようなツールを使用できますか?
使用開発ツールFlutter または Dart アプリをデバッグするためのスイート。
DevTools には、プロファイリング、ヒープの検査、 ウィジェット ツリーの検査、診断のログ記録、デバッグ、 実行されたコード行の監視、メモリ リークとメモリのデバッグ 断片化。詳細については、「開発ツールドキュメンテーション。
IDE を使用している場合は、 IDE のデバッガーを使用してアプリケーションをデバッグできます。
ホットリロードを実行するにはどうすればよいですか?
Flutter のステートフル ホット リロード機能は、迅速かつ簡単に実験するのに役立ちます。 UI を構築し、機能を追加し、バグを修正します。アプリを再コンパイルする代わりに 変更を加えるたびに、アプリを即座にホットリロードできます。 変更を反映してアプリが更新されます。 アプリの現在の状態は保持されます。
リアクトネイティブでは、 iOS シミュレーターのショートカットは ⌘R で、R を 2 回タップします。 Androidエミュレータ。
Flutter では、IntelliJ IDE または Android Studio を使用している場合、
「すべて保存」(⌘s/ctrl-s) を選択するか、
ツールバーのホットリロードボタン。もし、あんたが
コマンドラインでアプリを実行しているflutter run
、
タイプr
ターミナルウィンドウで。
次のように入力して完全な再起動を実行することもできます。R
の中に
ターミナルウィンドウ。
アプリ内の開発者メニューにアクセスするにはどうすればよいですか?
React Native では、デバイスを振ることで開発者メニューにアクセスできます: ⌘D iOS シミュレータの場合は ⌘M、Android エミュレータの場合は。
Flutter では、IDE を使用している場合は、IDE ツールを使用できます。始めたら
使用しているアプリケーションflutter run
と入力してメニューにアクセスすることもできますh
ターミナル ウィンドウで次のショートカットを入力するか、次のショートカットを入力します。
アクション | ターミナルのショートカット | デバッグ関数とプロパティ |
---|---|---|
アプリのウィジェット階層 | w |
debugDumpApp() |
アプリのレンダリングツリー | t |
debugDumpRenderTree() |
レイヤー | L |
debugDumpLayerTree() |
アクセシビリティ |
S (走査順序) またはU (ヒットテストの順序を逆にする) |
debugDumpSemantics() |
ウィジェットインスペクタを切り替えるには | i |
ウィジェットアプリ。 showWidgetInspectorOverride |
下書き線の表示を切り替えるには | p |
デバッグペイントサイズ有効 |
さまざまなオペレーティング システムをシミュレートするには | o |
デフォルトのターゲットプラットフォーム |
パフォーマンスオーバーレイを表示するには | P |
ウィジェットアプリ。 showパフォーマンスオーバーレイ |
スクリーンショットを flutterに保存するには。 png | s |
|
やめること | q |
アニメーション
適切にデザインされたアニメーションにより UI が直感的に感じられ、 洗練されたアプリのルックアンドフィールに貢献し、 そしてユーザーエクスペリエンスが向上します。 Flutter のアニメーション サポートにより、それが簡単になります 単純なアニメーションと複雑なアニメーションを実装します。 Flutter SDK には多くのマテリアル デザイン ウィジェットが含まれています 標準のモーションエフェクトを含む これらの効果は簡単にカスタマイズできます アプリをパーソナライズします。
React Native では、アニメーション API を使用してアニメーションを作成します。
Flutter では、Animation
クラスとAnimationController
クラス。Animation
はそれを理解する抽象クラスです
現在の値とその状態 (完了または拒否)。
のAnimationController
クラスでできること
アニメーションを順方向または逆方向に再生します。
またはアニメーションを停止してアニメーションを設定します
特定の値に設定してモーションをカスタマイズします。
単純なフェードイン アニメーションを追加するにはどうすればよいですか?
以下の React Native の例では、アニメーション化されたコンポーネントが、FadeInView
アニメーション API を使用して作成されます。
不透明度の初期状態、最終状態、および
遷移が発生する期間が定義されます。
アニメーションコンポーネントは内部に追加されますAnimated
成分、
不透明状態fadeAnim
マッピングされています
の不透明度にText
アニメーション化したいコンポーネント、
その後、start()
アニメーションを開始するために呼び出されます。
// React Native
const FadeInView = ({ style, children }) => {
const fadeAnim = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 10000
}).start();
}, []);
return (
<Animated.View style={{ ...style, opacity: fadeAnim }}>
{children}
</Animated.View>
);
};
...
<FadeInView>
<Text> Fading in </Text>
</FadeInView>
...
Flutter で同じアニメーションを作成するには、AnimationController
という名前のオブジェクトcontroller
そして期間を指定します。デフォルトでは、AnimationController
0.0 から 1.0 の範囲の値を線形に生成します。
指定された期間中。アニメーション コントローラーは新しい値を生成します
アプリを実行しているデバイスが新しいフレームを表示する準備ができたとき。
通常、このレートは 1 秒あたり約 60 値です。
を定義するとき、AnimationController
、
を渡す必要がありますvsync
物体。
の存在vsync
オフスクリーンを防ぐ
アニメーションが不必要なリソースを消費しないようにします。
ステートフル オブジェクトをvsync
追加することでTickerProviderStateMixin
クラス定義に。
アンAnimationController
TickerProvider が必要です。
これは、vsync
コンストラクターの引数。
あTween
の間の補間を記述します。
開始値と終了値、または入力からのマッピング
レンジから出力レンジまで。を使用するにはTween
物体
アニメーションを使用して、Tween
オブジェクトのanimate()
メソッドを渡して、Animation
変更するオブジェクト。
この例では、FadeTransition
ウィジェットが使用されており、opacity
財産は
にマッピングされるanimation
物体。
アニメーションを開始するには、次を使用しますcontroller.forward()
。
他の操作も、
などのコントローラーfling()
またrepeat()
。
この例では、FlutterLogo
ウィジェットは内部で使用されますFadeTransition
ウィジェット。
import 'package:flutter/material.dart';
void main() {
runApp(const Center(child: LogoFade()));
}
class LogoFade extends StatefulWidget {
const LogoFade({super.key});
@override
State<LogoFade> createState() => _LogoFadeState();
}
class _LogoFadeState extends State<LogoFade>
with SingleTickerProviderStateMixin {
late Animation<double> animation;
late AnimationController controller;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: const Duration(milliseconds: 3000),
vsync: this,
);
final CurvedAnimation curve = CurvedAnimation(
parent: controller,
curve: Curves.easeIn,
);
animation = Tween(begin: 0.0, end: 1.0).animate(curve);
controller.forward();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: animation,
child: const SizedBox(
height: 300,
width: 300,
child: FlutterLogo(),
),
);
}
}
カードにスワイプ アニメーションを追加するにはどうすればよいですか?
React Native では、次のいずれかです。PanResponder
また
スワイプ アニメーションにはサードパーティのライブラリが使用されます。
Flutter でスワイプ アニメーションを追加するには、Dismissible
ウィジェットを作成し、子ウィジェットをネストします。
return Dismissible(
key: Key(widget.key.toString()),
onDismissed: (dismissDirection) {
cards.removeLast();
},
child: Container(
//...
),
);
React Native および Flutter ウィジェットと同等のコンポーネント
次の表は、一般的に使用される React Native の一覧です。 対応する Flutter ウィジェットにマップされたコンポーネント および共通のウィジェットのプロパティ。
反応ネイティブコンポーネント | flutterウィジェット | 説明 |
---|---|---|
Button |
ElevatedButton |
ベーシックな上げボタン。 |
onPressed [必須] | ボタンがタップされたとき、またはその他の方法でアクティブ化されたときのコールバック。 | |
子供 | ボタンのラベル。 | |
Button |
TextButton |
ベーシックなフラットボタン。 |
onPressed [必須] | ボタンがタップされたとき、またはその他の方法でアクティブ化されたときのコールバック。 | |
子供 | ボタンのラベル。 | |
ScrollView |
ListView |
直線的に配置されたウィジェットのスクロール可能なリスト。 |
子供 | ( <Widget> [ ]) 表示する子ウィジェットのリスト。 | |
コントローラ | [ScrollController ] スクロール可能なウィジェットを制御するために使用できるオブジェクト。 |
|
項目範囲 | [ double ] null 以外の場合、子がスクロール方向に指定された範囲を持つように強制されます。 | |
スクロール方向 | [Axis ] スクロール ビューがスクロールする軸。 |
|
FlatList |
ListView.builder |
オンデマンドで作成されるウィジェットの線形配列のコンストラクター。 |
itemBuilder [必須] | [IndexedWidgetBuilder ] は、オンデマンドの子供たちを構築するのに役立ちます。このコールバックは、0 以上 itemCount 未満のインデックスを使用してのみ呼び出されます。 |
|
項目数 | [ int ] の能力を向上させます。ListView 最大スクロール範囲を推定します。 |
|
Image |
Image |
画像を表示するウィジェットです。 |
画像[必須] | 表示する画像。 | |
画像。資産 | 画像を指定するさまざまな方法のために、いくつかのコンストラクターが提供されています。 | |
幅、高さ、色、配置 | 画像のスタイルとレイアウト。 | |
フィット | レイアウト時に割り当てられたスペースに画像を埋め込みます。 | |
Modal |
ModalRoute |
以前のルートとの相互作用をブロックするルート。 |
アニメーション | ルートのトランジションと前のルートの前方トランジションを駆動するアニメーション。 | |
ActivityIndicator |
CircularProgressIndicator |
円に沿って進行状況を表示するウィジェット。 |
ストローク幅 | 円を描くために使用される線の幅。 | |
背景色 | 進行状況インジケーターの背景色。現在のテーマはThemeData.backgroundColor デフォルトでは。 |
|
ActivityIndicator |
LinearProgressIndicator |
線に沿って進行状況を表示するウィジェット。 |
価値 | この進行状況インジケーターの値。 | |
RefreshControl |
RefreshIndicator |
マテリアルの「スワイプして更新」イディオムをサポートするウィジェット。 |
色 | 進行状況インジケーターの前景色。 | |
更新時 | ユーザーがアプリを更新することを示すために更新インジケーターを十分にドラッグしたときに呼び出される関数。 | |
View |
Container |
子ウィジェットを囲むウィジェット。 |
View |
Column |
子を垂直配列で表示するウィジェット。 |
View |
Row |
子を水平配列で表示するウィジェット。 |
View |
Center |
子を自身の中心に配置するウィジェット。 |
View |
Padding |
指定されたパディングによって子を挿入するウィジェット。 |
パディング [必須] | [ EdgeInsets ] 子を挿入するスペースの量。 | |
TouchableOpacity |
GestureDetector |
ジェスチャーを検出するウィジェット。 |
オンタップ | タップが発生したときのコールバック。 | |
ダブルタップ時 | 同じ場所でタップが 2 回続けて発生した場合のコールバック。 | |
TextInput |
TextInput |
システムのテキスト入力コントロールへのインターフェイス。 |
コントローラ | [TextEditingController ] テキストにアクセスして変更するために使用されます。 |
|
Text |
Text |
単一のスタイルでテキスト文字列を表示するテキスト ウィジェット。 |
データ | [ String ] 表示するテキスト。 | |
テキスト方向 | [TextAlign ] テキストが流れる方向。 |
|
Switch |
Switch |
マテリアルデザインのスイッチ。 |
値[必須] | [ boolean ] このスイッチがオンかオフか。 | |
onChanged [必須] | [ callback ] ユーザーがスイッチをオンまたはオフに切り替えるときに呼び出されます。 | |
Slider |
Slider |
値の範囲から選択するために使用されます。 |
値[必須] | [ double ] スライダーの現在の値。 | |
onChanged [必須] | ユーザーがスライダーの新しい値を選択すると呼び出されます。 |